/*
*******************************************************************************
*                              (c) Copyright HighSun Techonology Company
*                                           All Rights Reserved
*
* File    : DSP2833x_adc.c
* By      : HuangXi
* Version : V0.1
* Datetime: 2012-02-13 PM 14:07
* Description: Define functions for ADC operation
*******************************************************************************
*/

#include <includes.h>

#define ADC_usDelay   (20000L)

#define ADC_CKPS      (2)
#define ADC_CPS       (1)
#define ADC_SHACQ     (15)


/* Function Declare */
interrupt void adc_isr(void);
static void read_duty_result(void);



typedef struct _sample_status
{
    INT8U which_point;
}SAMPLE_STATUS;


/* Record the status of sample */
SAMPLE_STATUS  sample_status;

/* Parameters of generator */
GENERATOR_PARAMETER generator_para;


/* Initialize the ADC register */
void init_adc(void)
{

   sample_status.which_point = 0;

   EALLOW;
   PieVectTable.ADCINT = &adc_isr;
   EDIS;


  /*
    *IMPORTANT*
    The ADC_cal function, which  copies the ADC calibration values from TI reserved
    OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
    Boot ROM. If the boot ROM code is bypassed during the debug process, the
    following function MUST be called for the ADC to function according
    to specification. The clocks to the ADC MUST be enabled before calling this
    function.
    See the device data manual and/or the ADC Reference
    Manual for more information.
  */
   ADC_cal();

   DELAY_US(ADC_usDelay);
   /*
     To powerup the ADC the ADCENCLK bit should be set first to enable
     clocks, followed by powering up the bandgap, reference circuitry, and ADC core.
     Before the first conversion is performed a 5ms delay must be observed
	 after power up to give all analog circuits time to power up and settle

     Please note that for the delay function below to operate correctly the
	 CPU_CLOCK_SPEED define statement in the DSP2833x_bsp.h file must
	 contain the correct CPU clock period in nanoseconds.
   */
   AdcRegs.ADCTRL3.all = 0x00E0; 
   DELAY_US(ADC_usDelay);
   

   /* ADC Clock is 3.125 MHz, SH width is 5.12us*/
   AdcRegs.ADCTRL3.bit.ADCCLKPS      = ADC_CKPS;
   AdcRegs.ADCTRL1.bit.CPS           = ADC_CPS;
   AdcRegs.ADCTRL1.bit.ACQ_PS        = ADC_SHACQ;
#if 1

   AdcRegs.ADCTRL3.bit.SMODE_SEL     = DEF_ENABLE;
   AdcRegs.ADCTRL1.bit.SEQ_CASC      = DEF_ENABLE;
   AdcRegs.ADCTRL1.bit.CONT_RUN      = DEF_DISABLE;
   
   AdcRegs.ADCMAXCONV.all            = 0x7;

   AdcRegs.ADCCHSELSEQ1.bit.CONV00   = 0x0;
   AdcRegs.ADCCHSELSEQ1.bit.CONV01   = 0x1;
   AdcRegs.ADCCHSELSEQ1.bit.CONV02   = 0x2;
   AdcRegs.ADCCHSELSEQ1.bit.CONV03   = 0x3;
   
   AdcRegs.ADCCHSELSEQ2.bit.CONV04   = 0x4;
   AdcRegs.ADCCHSELSEQ2.bit.CONV05   = 0x5;
   AdcRegs.ADCCHSELSEQ2.bit.CONV06   = 0x6;
   AdcRegs.ADCCHSELSEQ2.bit.CONV07   = 0x7;


   /* Reset the pointer to CONV00 */
   AdcRegs.ADCTRL2.bit.RST_SEQ1  = 1;
   AdcRegs.ADCTRL2.bit.RST_SEQ2  = 1;




   /* Clear the irq flag of SEQ1  */
   AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
   AdcRegs.ADCST.bit.INT_SEQ2_CLR = 1;

   

   /* Enable the irq of PIE level */
   PieCtrlRegs.PIEIER1.bit.INTx6    = DEF_ENABLE;


   /* Enable the irq of CPU level */
   IER |= M_INT1;

   
   /* Enable SEQ1 irq */
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = DEF_ENABLE;
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2 = DEF_ENABLE;


   /* Read the duty result for all channel */
   read_duty_result();

   DELAY_US(ADC_usDelay);

    /* Trigger ADC sample */
  //  AdcRegs.ADCTRL2.bit.SOC_SEQ1 = DEF_ENABLE;
  //  AdcRegs.ADCTRL2.bit.SOC_SEQ2 = DEF_ENABLE;
    
#else
   AdcRegs.ADCTRL1.bit.ACQ_PS = 1;  // Sequential mode: Sample rate   = 1/[(2+ACQ_PS)*ADC clock in ns]
                        //                     = 1/(3*40ns) =8.3MHz (for 150 MHz SYSCLKOUT)
					    //                     = 1/(3*80ns) =4.17MHz (for 100 MHz SYSCLKOUT)
					    // If Simultaneous mode enabled: Sample rate = 1/[(3+ACQ_PS)*ADC clock in ns]
   AdcRegs.ADCTRL3.bit.ADCCLKPS = 0;
   AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;        // 1  Cascaded mode
   AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x1;
   AdcRegs.ADCTRL1.bit.CONT_RUN = 1;       // Setup continuous run

   AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;       // Enable Sequencer override feature
   AdcRegs.ADCCHSELSEQ1.all = 0x0;         // Initialize all ADC channel selects to A0
   AdcRegs.ADCCHSELSEQ2.all = 0x0;
   AdcRegs.ADCCHSELSEQ3.all = 0x0;
   AdcRegs.ADCCHSELSEQ4.all = 0x0;
   AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x1;  // convert and store in 8 results registers



// Start SEQ1
   AdcRegs.ADCTRL2.all = 0x2000;


   while (1)
   {
       while (AdcRegs.ADCST.bit.INT_SEQ1== 0){}


       debug_print("%s%d%s","Hello result:",( (AdcRegs.ADCRESULT0)>>4),"\n\r");
       AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;


       AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;
   }
#endif
}


Uint16 sample_result_Uab[SAMPLE_POINTS] = {0};
Uint16 sample_result_Ucb[SAMPLE_POINTS] = {0};
Uint16 sample_result_Ia[SAMPLE_POINTS]  = {0};
Uint16 sample_result_Ic[SAMPLE_POINTS]  = {0};
Uint16 IL = 0;

/* ISR  of ADC */
interrupt void adc_isr(void)
{
   // DINT;
    
    /* Get sample result for each channel */
    //adc_put_sample_data(sample_status.which_point, AD_REF_A, (AdcRegs.ADCRESULT0>>4));
    //debug_print("%s%d%s","r0:",( (AdcRegs.ADCRESULT0)>>4),"\n\r");

    //adc_put_sample_data(sample_status.which_point, AD_REF_B, (AdcRegs.ADCRESULT1>>4));
    //debug_print("%s%d%s","r1:",( (AdcRegs.ADCRESULT1)>>4),"\n\r");

   // adc_put_sample_data(sample_status.which_point, UFAB,     (AdcRegs.ADCRESULT2>>4));
    sample_result_Uab[sample_status.which_point] = ((AdcRegs.ADCRESULT2)>>4);
	//LED1=~LED1;
    
    //adc_put_sample_data(sample_status.which_point, IFA,      (AdcRegs.ADCRESULT3>>4));
    sample_result_Ia[sample_status.which_point] = ((AdcRegs.ADCRESULT3)>>4);

    //adc_put_sample_data(sample_status.which_point, UFCB,     (AdcRegs.ADCRESULT4>>4));
    //debug_print("%s%d%s","r4:",( (AdcRegs.ADCRESULT4)>>4),"\n\r");
    sample_result_Ucb[sample_status.which_point] = ((AdcRegs.ADCRESULT4)>>4);


    //adc_put_sample_data(sample_status.which_point, IFC,      (AdcRegs.ADCRESULT5>>4));
   // debug_print("%s%d%s","r5:",( (AdcRegs.ADCRESULT5)>>4),"\n\r");
    sample_result_Ic[sample_status.which_point] = ((AdcRegs.ADCRESULT5)>>4);

    //adc_put_sample_data(sample_status.which_point, UXAB,     (AdcRegs.ADCRESULT6>>4));
    //debug_print("%s%d%s","r6:",( (AdcRegs.ADCRESULT6)>>4),"\n\r");



   // adc_put_sample_data(sample_status.which_point, AD_B3,    (AdcRegs.ADCRESULT7>>4));
    //debug_print("%s%d%s","r7:",( (AdcRegs.ADCRESULT7)>>4),"\n\r");


    //adc_put_sample_data(sample_status.which_point, ULO,      (AdcRegs.ADCRESULT8>>4));
    //debug_print("%s%d%s","r8:",( (AdcRegs.ADCRESULT8)>>4),"\n\r");


    //adc_put_sample_data(sample_status.which_point, ILO,      (AdcRegs.ADCRESULT9>>4));
    //debug_print("%s%d%s","r9:",( (AdcRegs.ADCRESULT9)>>4),"\n\r");



    //adc_put_sample_data(sample_status.which_point, AD_A5,    (AdcRegs.ADCRESULT10>>4));
    //debug_print("%s%d%s","r10:",( (AdcRegs.ADCRESULT10)>>4),"\n\r");


   // adc_put_sample_data(sample_status.which_point, AD_B5,    (AdcRegs.ADCRESULT11>>4));
    //debug_print("%s%d%s","r11:",( (AdcRegs.ADCRESULT11)>>4),"\n\r");


    //adc_put_sample_data(sample_status.which_point, AD_A6,    (AdcRegs.ADCRESULT12>>4));
    //debug_print("%s%d%s","r12:",( (AdcRegs.ADCRESULT12)>>4),"\n\r");

    //adc_put_sample_data(sample_status.which_point, AD_B6,    (AdcRegs.ADCRESULT13>>4));
    //debug_print("%s%d%s","r13:",( (AdcRegs.ADCRESULT13)>>4),"\n\r");


    //adc_put_sample_data(sample_status.which_point, AD_A7,    (AdcRegs.ADCRESULT14>>4));
    //debug_print("%s%d%s","r14:",( (AdcRegs.ADCRESULT14)>>4),"\n\r");

    //adc_put_sample_data(sample_status.which_point, AD_B7,    (AdcRegs.ADCRESULT15>>4));
    //debug_print("%s%d%s","r15:",( (AdcRegs.ADCRESULT15)>>4),"\n\r");

    /* Sample counter increment 1 */
    sample_status.which_point++;

 
        
    GpioDataRegs.GPBTOGGLE.bit.GPIO49 = 1;
    
    /* See if reach max sample point */
    if (sample_status.which_point >= SAMPLE_POINTS)
    {
       // debug_print("%s%s%s","12:","34","\n\r");

        GpioDataRegs.GPBSET.bit.GPIO48 = 1;
       
        /* Stop Timer1 */
        CpuTimer0Regs.TCR.bit.TSS = 1;


        
        /* Wrap the counter */
        sample_status.which_point = 0;

        /* Get the parameters of generator */
        //compute_generator_parameter(&generator_para);
        debug_Uab(&sample_result_Uab[0]);
        debug_Ucb(&sample_result_Ucb[0]);
        debug_Ia(&sample_result_Ia[0]);
        debug_Ic(&sample_result_Ic[0]);
        debug_IL(((AdcRegs.ADCRESULT9)>>4));
        debug_UL(((AdcRegs.ADCRESULT8)>>4));
        cal_P_Q_S();
    }



    /* Re-trigger the ADC */
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
   // AdcRegs.ADCTRL2.bit.RST_SEQ1   = 1;

    /* Re-trigger the ADC */
    AdcRegs.ADCST.bit.INT_SEQ2_CLR = 1;
   // AdcRegs.ADCTRL2.bit.RST_SEQ2   = 1;

    /* ACK all irqs in same group */
    PieCtrlRegs.PIEACK.all         = PIEACK_GROUP1;

   // EINT;
}


/* Read the duty result */
static void read_duty_result(void)
{
   Uint16 adc_result = 0;
   
   adc_result = ((AdcRegs.ADCRESULT0)>>4);
   adc_result = ((AdcRegs.ADCRESULT1)>>4);
   adc_result = ((AdcRegs.ADCRESULT2)>>4);
   adc_result = ((AdcRegs.ADCRESULT3)>>4);
   adc_result = ((AdcRegs.ADCRESULT4)>>4);
   adc_result = ((AdcRegs.ADCRESULT5)>>4);
   adc_result = ((AdcRegs.ADCRESULT6)>>4);
   adc_result = ((AdcRegs.ADCRESULT7)>>4);
   adc_result = ((AdcRegs.ADCRESULT8)>>4);
   adc_result = ((AdcRegs.ADCRESULT9)>>4);
   adc_result = ((AdcRegs.ADCRESULT10)>>4);
   adc_result = ((AdcRegs.ADCRESULT11)>>4);
   adc_result = ((AdcRegs.ADCRESULT12)>>4);
   adc_result = ((AdcRegs.ADCRESULT13)>>4);
   adc_result = ((AdcRegs.ADCRESULT14)>>4);
   adc_result = ((AdcRegs.ADCRESULT15)>>4);

   adc_result = adc_result;
}


/* Set the sample cycle */
void start_ad_sample(const float64 freq, const Uint32 sample_points)
{
    Uint32 clocks = 0;
    
    GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1;
    GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1;

   
    /* Stop the Timer1 and init the sample counter */
    //CpuTimer0Regs.TCR.bit.TSS = 1;
    sample_status.which_point = 0;
    
    /* Trigger the N-0 point ADC sample */
    AdcRegs.ADCTRL2.bit.SOC_SEQ1 = DEF_ENABLE;
    //AdcRegs.ADCTRL2.bit.SOC_SEQ2 = DEF_ENABLE;
    
    clocks =   (Uint32)((float64)SYS_OSC_CLOCK / (freq * (float64)sample_points));

    
	/* Set the period register */
    CpuTimer0Regs.PRD.all = clocks;

	/* Reload the  value of PRD */
    CpuTimer0Regs.TCR.bit.TRB=1;
    
    /* Start Timer1 */
    CpuTimer0Regs.TCR.bit.TSS = 0;
}

/* ISR of timer1 */
interrupt void ISRTimer1(void)
{
   // DINT;
    
	//LED1=~LED1;
    
    //debug_print("%s%d%s","w:",sample_status.which_point,"\n\r");
#if 0
    /* Sample counter increment 1 */
    sample_status.which_point++;



    /* Trigger ADC sample */
    AdcRegs.ADCTRL2.bit.SOC_SEQ1 = DEF_ENABLE;
    AdcRegs.ADCTRL2.bit.SOC_SEQ2 = DEF_ENABLE;

    /* Clear the reach to 0 flag */
    CpuTimer1Regs.TCR.bit.TIF=1;

	/* Reload the  value of PRD */
    CpuTimer1Regs.TCR.bit.TRB=1;
 #endif

    GpioDataRegs.GPBTOGGLE.bit.GPIO49 = 1;

    /* Clear the reach to 0 flag */
    CpuTimer1Regs.TCR.bit.TIF=1;

	/* Reload the  value of PRD */
    CpuTimer1Regs.TCR.bit.TRB=1;

    EDIS;

 //   EINT;
}

#if 1
/*Get Uab*/
float64 get_Uab(void)
{
    return (float64)generator_para.Uab;
}
#endif


interrupt void ISRTimer0(void)
{
    
    //CpuTimer0.InterruptCount++;


    /* Trigger ADC sample */
    AdcRegs.ADCTRL2.bit.SOC_SEQ1 = DEF_ENABLE;

    
    /* Clear the reach to 0 flag */
    CpuTimer0Regs.TCR.bit.TIF=1;

	/* Reload the  value of PRD */
    CpuTimer0Regs.TCR.bit.TRB=1;

    /* Acknowledge this interrupt to receive more interrupts from group 1 */
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    
    
    
}

